{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div align=center><b><font size=6>Python3基础笔记</font></b></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以jupyter notebook的形式，提供交互式的python3入门教程，含练习题若干。\n",
    "- *Copyright(c) 2020 罗子牛 Luo, Ziniu.*\n",
    "- *This project is licensed under the terms of the MIT license.*\n",
    "- *Github: [https://github.com/luozn15/Python3-Introduction-Notebook](https://github.com/luozn15/Python3-Introduction-Notebook)*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 简介与工具准备\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 Python历史"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Python**是一种面向对象的解释型计算机程序设计语言，其使用，具有跨平台的特点，可以在Linux、MacOS以及Windows系统中搭建环境并使用，其编写的代码在不同平台上运行时，几乎不需要做较大的改动。\n",
    "\n",
    "* Windows\n",
    "* MacOS\n",
    "* Linux\n",
    "* RaspberryPi 树莓派\n",
    "* Arduino\\*\n",
    "\n",
    "此外，**Python**的强大之处在于它的应用领域范围之广，遍及 **人工智能** 、 **科学计算** 、Web开发、系统运维、大数据及云计算、金融、游戏开发等。实现其强大功能的前提，就是**Python**具有数量庞大且功能相对完善的标准库和第三方库(包)。通过对库的引用，能够实现对不同领域业务的开发。\n",
    "\n",
    "<img src=\"https://flink.apache.org/img/blog/2020-08-04-pyflink-pandas/python-scientific-stack.png\" width=\"400\" div align=\"left\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 Anaconda安装"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Anaconda**是一个包含180+的科学包及其依赖项的python发行版本。其包含的科学包包括：**conda, numpy, scipy, jupyter notebook**等。\n",
    "\n",
    "安装**Anaconda**能快速搭建数据分析的环境，并方便日后管理多个python环境。\n",
    "\n",
    "* 下载Anaconda Installer [Anaconda Individual Edition, Your data science toolkit](https://www.anaconda.com/products/individual)\n",
    " \n",
    "打开Anaconda Installers开始安装，如果不清楚选项的含义，保留默认选项即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 jupyter notebook使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.1 jupyter notebook 在线试用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本节课内容对于计算性能要求不高，大家若没有完成本地Anaconda安装，可以暂时使用在线的jupyter notebook服务\n",
    "\n",
    "* [jupyter notebook 在线试用](https://jupyter.org/try)\n",
    "* [google colab](https://colab.research.google.com/)\n",
    "\n",
    "但从下节课开始，可能需要使用本地的数据，需要较多的计算资源，请大家尽可能在自己的电脑上安装好Anaconda。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.2 本地使用jupyter notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "进入某一工作目录下，从地址栏输入`jupyter notebook`，回车\n",
    "<img src=\"https://img-blog.csdnimg.cn/20190908135217739.png\" width=\"500\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.3 新建个人目录/程序/终端环境"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://raw.githubusercontent.com/MrKaiWu/PythonForYou/0eb359b3b0060c1378bb22080799f9d35d876b99/chapter1(1116%E6%9B%B4%E6%96%B0)/pics/explorer.png\" width=\"800\">\n",
    "\n",
    "点击右上角 'new' 按钮,在弹出菜单中:\n",
    "\n",
    "* new-> python3 : 创建一个python3的程序文档(.ipynb)\n",
    "* new-> folder : 创建一个目录\n",
    "\n",
    "点击右上角 'upload' 按钮, 可以“上传”个人的文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.4 熟悉工具栏操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://raw.githubusercontent.com/MrKaiWu/PythonForYou/0eb359b3b0060c1378bb22080799f9d35d876b99/chapter1(1116%E6%9B%B4%E6%96%B0)/pics/toolbar.png\" width=\"500\">\n",
    "\n",
    "上图所示区域就是工具栏。鼠标悬停可以显示各按钮含义。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3.5 熟悉快捷键操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "详细的键盘快捷操作信息可以点击工具栏的如下按钮查看到:\n",
    "\n",
    "<img src=\"https://raw.githubusercontent.com/MrKaiWu/PythonForYou/0eb359b3b0060c1378bb22080799f9d35d876b99/chapter1(1116%E6%9B%B4%E6%96%B0)/pics/shortcut.png\" width=\"50\">\n",
    "\n",
    "command 模式下最常用的键盘快捷键:\n",
    "\n",
    "* ↑和↓ ： 切换代码框（cell）\n",
    "* shift + enter : 运行当前cell并挪动到下一个cell\n",
    "* ctrl + enter ：运行当前cell，保持在当前cell\n",
    "* b : 在当前cell下面插入新cell\n",
    "* a : 在当前cell上面插入新cell\n",
    "* dd (敲击d键两下): 删除当前cell\n",
    "* m : 将当前cell由code模式转换成markdown模式\n",
    "* y : 将当前cell由markdown模式转换成code模式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4 练习题：熟悉jupyter notebook操作<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 鼠标单击选中下面的代码块，快捷键`shift + enter`执行该代码块\n",
    "2. 自由使用快捷键和命令，尝试**增加cell、复制cell、切换cell、删除cell等**各种操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.302480Z",
     "start_time": "2025-10-01T07:14:22.087472Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Python 3.12.7\n"
     ]
    }
   ],
   "source": [
    "# 查看当前python版本\n",
    "!python --version"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. python基础语法\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 = 赋值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`=`表示将右侧的值赋予左侧的变量，经过赋值的变量可以去参与各种运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.337772Z",
     "start_time": "2025-10-01T07:14:22.330767Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "12.0"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "width = 2.0\n",
    "height = 6.0\n",
    "area = width * height\n",
    "area"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "赋与的值可以是数值，也可以是其它任意变量类型，如字符串："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.477897Z",
     "start_time": "2025-10-01T07:14:22.471444Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hello world'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "字符串a = 'hello '      #虽然不建议，但变量名也可以是中文\n",
    "字符串b = 'world'\n",
    "字符串a + 字符串b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python变量命名比较自由，如以上的`width, height, 字符串a, 字符串b`，但也需要注意一些[变量命名规则](https://blog.csdn.net/yirentianran/article/details/79567177)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "此外，需要注意的是，一个等号`=`表示赋值，而两个等号`==`表示判断，`!=`表示不等。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.626913Z",
     "start_time": "2025-10-01T07:14:22.617578Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_a = 2\n",
    "num_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.781733Z",
     "start_time": "2025-10-01T07:14:22.775148Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_a == 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:22.891575Z",
     "start_time": "2025-10-01T07:14:22.886501Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 != num_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 print()与input()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`print()`会打印显示一些文本和结果，便于验证和显示数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:23.039072Z",
     "start_time": "2025-10-01T07:14:23.034339Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World!\n",
      "现在是 2025-10-01 15:18:26\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "print('Hello World!')\n",
    "print('现在是 ' + time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "除了数值和文本以外，`print()`也可以打印显示列表、字典等复合的类型变量，可以用`,`分隔多个打印对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:23.136757Z",
     "start_time": "2025-10-01T07:14:23.132545Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 4, 'helloworld']\n",
      "{'a': 1, 'b': 2}\n"
     ]
    }
   ],
   "source": [
    "list_a = [1,2,4,'helloworld']\n",
    "dict_a = {'a':1,'b':2}\n",
    "print(list_a)\n",
    "print(dict_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 **jupyter notebook** 这种交互式的编程中，即使不使用`print()`,每个代码块会自动打印最后一行的返回值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:23.265243Z",
     "start_time": "2025-10-01T07:14:23.260541Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_a = 1\n",
    "num_b = 2.0\n",
    "num_a + num_b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`input()`会弹出会话框，请求一个输入，并将会话的输入作为input函数的输出。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.223531Z",
     "start_time": "2025-10-01T07:14:23.367012Z"
    }
   },
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "what's the time now?  uuu\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "it's uuu now\n"
     ]
    }
   ],
   "source": [
    "a = input(\"what's the time now? \") # a的取值来源于input输入\n",
    "print(\"it's \"+ a + \" now\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.3 注释"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在一行代码中，`#`往后的语句将不会被执行，仅作为代码阅读的注解，称为注释"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.436757Z",
     "start_time": "2025-10-01T07:14:28.430432Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 1 + 2 #这是一行注释\n",
    "a # 变量a被赋与1+2的值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当需要注释多行时，可以在前后使用三个连续单引号`'''`或三个连续双引号`\"\"\"`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.569316Z",
     "start_time": "2025-10-01T07:14:28.563983Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 1 + 2\n",
    "'''\n",
    "多行注释可以用三个引号\n",
    "多行注释可以用三个引号\n",
    "多行注释可以用三个引号\n",
    "'''\n",
    "a + 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在写代码时多使用注释，作一些记录和解释，不仅方便其它人来阅读，也有利于自己检查错误。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.4 练习题：多边形面积<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对于任意多边形，其顶点坐标为$(x_{0},y_{0}),(x_{1},y_{1}),(x_{2},y_{2}),...,(x_{n},y_{n}),(x_{0},y_{0})$,则其面积的计算公式有：\n",
    "\n",
    "* 1. $$S=\\frac{1}{2}\\sum \\left ( x_{i}\\, y_{i+1}-y_{i}\\, x_{i+1} \\right )$$\n",
    "* 2. $$S=\\frac{1}{2}\\sum \\left ( x_{i}+ x_{i+1}\\right )\\left (y_{i}- y_{i+1} \\right )$$\n",
    "<img src=\"https://www.shuxuele.com/geometry/images/area-irregular-polygon2.gif\" width=\"300\"/>\n",
    "\n",
    "以下代码用两种方式求取了图示多边形的面积，结果分别为`S_1`和`S_2`。**试写代码判断两个结果是否相等，然后使用`print()`打印输出两个结果。**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.694177Z",
     "start_time": "2025-10-01T07:14:28.690304Z"
    }
   },
   "outputs": [],
   "source": [
    "X = [1.9, 4.0, 3.6, 5.0, 2.7, 0.7, 1.9]\n",
    "Y = [1.0, 1.6, 2.5, 3.5, 4.7, 2.3, 1.0]\n",
    "\n",
    "S_1 = 0\n",
    "for i in range(len(X)-1):\n",
    "    S_1 += X[i]*Y[i+1]-Y[i]*X[i+1]     #公式1方法求面积\n",
    "    \n",
    "S_2 = 0\n",
    "for i in range(len(X)-1):\n",
    "    S_2 += (X[i]+X[i+1])*(Y[i+1]-Y[i]) #公式2方法求面积\n",
    "    \n",
    "    \n",
    "########在此行以下输入代码，完成题目要求\n",
    "\n",
    "#print(\"S_1 = \",S_1)\n",
    "#print(\"S_2 = \",S_2)\n",
    "#print(S_1 == S_2) # S_1 与 S_2 很相近，但不严格相等，这与计算机保存变量的精度有关。\n",
    "\n",
    "########输入代码结束"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. python变量类型\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也叫数据类型，Python共有6种基础的变量类型。\n",
    "* 数值型 Numbers\n",
    "* 字符串 String\n",
    "* 列表 List\n",
    "* 元组 Tuple\n",
    "* 集合 Sets\n",
    "* 字典 Dictionaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`type()`方法，我们能查看变量的类型。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.1 数值类型 Number"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类型用于存储数值，又可进一步划分为："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 整数型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.788442Z",
     "start_time": "2025-10-01T07:14:28.782814Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_a = -1 \n",
    "type(num_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 浮点型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:28.935621Z",
     "start_time": "2025-10-01T07:14:28.930801Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_b = 3/2\n",
    "type(num_b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 布尔型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.057417Z",
     "start_time": "2025-10-01T07:14:29.052633Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(bool, True)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_c =  (num_a == -1) #布尔型只有True 和False 两个取值\n",
    "type(num_c), num_c"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* 复数型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.176550Z",
     "start_time": "2025-10-01T07:14:29.171817Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "complex"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_d = -5+4j\n",
    "type(num_d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1.1 算数运算符\n",
    "以a = 10 , b = 21为例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.274392Z",
     "start_time": "2025-10-01T07:14:29.270488Z"
    }
   },
   "outputs": [],
   "source": [
    "a = 10\n",
    "b = 21"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.319285Z",
     "start_time": "2025-10-01T07:14:29.313350Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "31"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a+b "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.451543Z",
     "start_time": "2025-10-01T07:14:29.446303Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-11"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a-b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.590354Z",
     "start_time": "2025-10-01T07:14:29.585155Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "210"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a*b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.722194Z",
     "start_time": "2025-10-01T07:14:29.716657Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.1"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b/a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:29.854202Z",
     "start_time": "2025-10-01T07:14:29.848757Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#取模，返回整除的余数\n",
    "b%a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.006633Z",
     "start_time": "2025-10-01T07:14:30.001732Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9261"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#幂\n",
    "b**3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.147103Z",
     "start_time": "2025-10-01T07:14:30.121595Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#整除\n",
    "b//a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1.2 比较运算符\n",
    "    以a = 10 , b = 20为例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.261994Z",
     "start_time": "2025-10-01T07:14:30.256708Z"
    }
   },
   "outputs": [],
   "source": [
    "a = 10\n",
    "b = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.290060Z",
     "start_time": "2025-10-01T07:14:30.284442Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#等于\n",
    "a == b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.430678Z",
     "start_time": "2025-10-01T07:14:30.425699Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#不等于\n",
    "a != b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.559500Z",
     "start_time": "2025-10-01T07:14:30.554265Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#大于\n",
    "a>b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.698233Z",
     "start_time": "2025-10-01T07:14:30.693966Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#大于等于\n",
    "2*a>=b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "小于`<`和小于等于`<=`同理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1.3 逻辑运算符\n",
    "    以a = True , b = False为例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.828751Z",
     "start_time": "2025-10-01T07:14:30.825397Z"
    }
   },
   "outputs": [],
   "source": [
    "a = True\n",
    "b = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:30.893253Z",
     "start_time": "2025-10-01T07:14:30.888174Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#与\n",
    "a and b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.269957Z",
     "start_time": "2025-10-01T07:14:31.265330Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#或\n",
    "a or b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.452062Z",
     "start_time": "2025-10-01T07:14:31.446571Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#非\n",
    "not a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.2 字符串类型 String"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串是字符的序列。字符串需要使用`' '`或`\" \"`括起来。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.577032Z",
     "start_time": "2025-10-01T07:14:31.572656Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a = 'this is a String'\n",
    "type(string_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`len()`函数获得字符串的长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.696028Z",
     "start_time": "2025-10-01T07:14:31.690986Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(string_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`in`，`not in`判断字符串的包含关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.821248Z",
     "start_time": "2025-10-01T07:14:31.816704Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'this' in string_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:31.964673Z",
     "start_time": "2025-10-01T07:14:31.959814Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'string' not in string_a #区分大小写"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串可以通过`+`进行拼接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.139043Z",
     "start_time": "2025-10-01T07:14:32.134009Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is a String, too'"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a + ', too'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.1 字符串索引与切片"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字符串可以被视作从左到右的字符序列，使用字符在序列中的序号，可以索引到对应字符，或对字符串进行切片。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.276753Z",
     "start_time": "2025-10-01T07:14:32.272557Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is a String'"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.434944Z",
     "start_time": "2025-10-01T07:14:32.430246Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('t', 'g')"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[0], string_a[-1] #单个序号表示索引"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`:`分隔表示切片，格式为`start:end:step`。step默认为1，此时切片格式可简化为`start:end`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.557270Z",
     "start_time": "2025-10-01T07:14:32.553121Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[0:7] #区间为[a,b),索引切片包括第a位，但不包括第b位"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.676048Z",
     "start_time": "2025-10-01T07:14:32.671944Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is a'"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[:9] #当从头开始切片时，0可以省略"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.789886Z",
     "start_time": "2025-10-01T07:14:32.782283Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "' String'"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[9:] #切片至字符串末尾"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.882882Z",
     "start_time": "2025-10-01T07:14:32.878558Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is a String'"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[:] #当从头到尾的切片，即字符串本身"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:32.998751Z",
     "start_time": "2025-10-01T07:14:32.994413Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'this is'"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[0:7:1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:33.112479Z",
     "start_time": "2025-10-01T07:14:33.107695Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'ti s'"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[0:7:2] #步长为2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:33.210896Z",
     "start_time": "2025-10-01T07:14:33.204705Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'gnirtS a si siht'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_a[::-1] #步长为-1,即字符串逆序"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2.2 字符串split，join"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`split()`分割字符串为列表，`join()`将列表连接为字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:33.384223Z",
     "start_time": "2025-10-01T07:14:33.375006Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['info', 'tsinghua', 'edu', 'cn']"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "string_b = 'info.tsinghua.edu.cn'\n",
    "splitted = string_b.split('.')\n",
    "splitted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:33.594296Z",
     "start_time": "2025-10-01T07:14:33.588830Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'info。tsinghua。edu。cn'"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'。'.join(splitted)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.3 元组 Tuple，列表 List，字典 Dictionary，集合Set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3.1 元组 Tuple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用一对`()`定义元组，其中元素使用`,`分隔。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:34.294425Z",
     "start_time": "2025-10-01T07:14:34.290035Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2020, 'Nov.', 14)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tuple_a = (2020, 'Nov.', 14)\n",
    "tuple_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组可以使用序号对元素进行索引。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:34.726909Z",
     "start_time": "2025-10-01T07:14:34.722706Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2020, 'Nov.')"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tuple_a[0:2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组的元素是不能直接修改的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:34.965967Z",
     "start_time": "2025-10-01T07:14:34.909268Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'tuple' object does not support item assignment",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[53], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m tuple_a[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m15\u001b[39m\n",
      "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
     ]
    }
   ],
   "source": [
    "tuple_a[-1] = 15 #对元组元素直接赋值会报错"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "元组的解包操作可以对多个元素进行快速赋值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-01T07:14:35.229460Z",
     "start_time": "2025-10-01T07:14:15.884810Z"
    }
   },
   "outputs": [],
   "source": [
    "Y,M,D = tuple_a #元组解包\n",
    "print(Y)\n",
    "print(M,D)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3.2 列表 List"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用一对`[]`定义列表，其中元素使用`,`分隔。\n",
    "<img src=\"\" width=\"500\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a = ['twenty_twenty', 1, '14th']\n",
    "list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`len()`函数获得列表的长度"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "len(list_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表的索引、切片、拼接方式与字符串相同"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a + ['9am'] \n",
    "list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "和字符串类似的，使用`in`，`not in`也判断的元素是否包含于列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "'15th' in list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`append()`方法向列表末尾追加元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a.append('9am')# list_a = list_a+'9am'\n",
    "list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "不同于元组，列表的元素是可以直接修改的。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a[0]= 2020\n",
    "list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用`list()`方法能将字符串、元组等转化为列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "string_a = 'this is a String'\n",
    "list(string_a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "tuple_a = (2020, 'Nov.', 14)\n",
    "list(tuple_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python列表自带`.reverse()`方法，能反转列表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_a.reverse()\n",
    "list_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3.3 字典 Dictionary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典是一种映射类型(mapping type)，它是一个无序的‘键：值’对集合。每一个元素包含key、value两部分。\n",
    "<img src=\"https://www.learnbyexample.org/wp-content/uploads/python/Dictionary-Key-Value-Pairs-Illustration.png\" width=\"500\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_a = {'Jack':1557,'Tom':1320,'Rose':1886}\n",
    "dict_a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "字典的一些基本操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_a['Tom']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_a['John'] = 2020\n",
    "dict_a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_a.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "dict_a.values()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for k,v in dict_a.items():\n",
    "    print(\"key\",k,\"value\",v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3.4 集合 Set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "集合具有不重复的特性，基本功能是去重。可以用`{}`或`set()`来创建集合。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "set_b ={0,1,1}\n",
    "set_b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "list_a = [0,1,2,3,2,1,0]\n",
    "set_a = set(list_a)\n",
    "list(set_a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.4 类型转换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int('1')#从字符串转换为整数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "float('1')#从字符串转换为浮点数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "str(1)#从浮点数转换为字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3.5 练习题：字符串拼接整理<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本题通过爬虫的方式抓取了[ArchDaily首页](https://www.archdaily.com/)呈现的链接后缀字符串，以列表形式存储在变量`suffixes`中。\n",
    "\n",
    "1. **拼合链接**:试从中任选一个链接后缀，与ArchDaily首页网址拼合成完整的项目链接，如 \n",
    "    *  https://www.archdaily.com/951061/cana-guesthouse-carl-gerges-architects\n",
    "2. **整理语句**：观察到，后缀中有以`'-'`分隔的语句。任选一个后缀，试去除前面的数字和斜线，并将后面语句中的分隔符`'-'`替换为空格`' '`。\n",
    "    * '/951061/cana-guesthouse-carl-gerges-architects'  --->  'cana guesthouse carl gerges architects'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import re\n",
    "\n",
    "url='https://www.archdaily.com/' #ArchDaily首页网址\n",
    "headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'}\n",
    "text = requests.get(url,headers=headers).text\n",
    "suffixes=re.findall(\"href=\\\"(.*?)\\\"><span itemprop=\\'name\\'\",text)\n",
    "suffixes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# 1. 拼合链接\n",
    "url='https://www.archdaily.com/' #ArchDaily首页网址\n",
    "########在此行以下输入代码，完成题目要求\n",
    "\n",
    "\n",
    "#######输入代码结束\n",
    "print(full_link)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出如：https://www.archdaily.com/951061/cana-guesthouse-carl-gerges-architects"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# 2. 整理语句\n",
    "########在此行以下输入代码，完成题目要求\n",
    "\n",
    "\n",
    "#######输入代码结束\n",
    "print(pure_statement)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出如：'cana guesthouse carl gerges architects'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 控制流\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "截止到现在，以上代码都是从上到下顺序执行的。如果我们想改变这一工作流程，应该怎么做？就像这样的情况：你需要程序作出一些决定，并依据不同的情况去完成不同的事情，例如依据每天时间的不同打印出 '早上好'  或 '晚上好' ？\n",
    "\n",
    "这将通过控制流语句来实现的。在 Python 中有三种控制流语句——`if-else` `for` 和 `while`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.1 if-else"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`if`语句用以检查条件：如果 条件为真（True），我们将运行一块语句（if-block），否则 我们将运行另一块语句（else-block）。其中 else 从句是可选的。\n",
    "<img src=\"https://pic2.zhimg.com/v2-1eac9981e94bb46842cf8fd9a6d5c779_b.png\" width=\"500\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取当前时间的小时数\n",
    "import time\n",
    "current_hour = time.localtime().tm_hour\n",
    "print('current_hour: '+ str(current_hour))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#控制流代码\n",
    "if current_hour <= 10:\n",
    "    print('讲课进度还可以')\n",
    "else:\n",
    "    print('进度偏慢，后面要快点了')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意，python使用缩进来判断控制流的作用范围和嵌套关系，缩进对齐的if和else才是对应关系。例如:\n",
    "```python\n",
    "if current_hour <= 5:\n",
    "    if current_hour > 7:\n",
    "        print('...')\n",
    "    else:\n",
    "        print('...')\n",
    "else:\n",
    "    print('...')\n",
    "```\n",
    "建议使用Tab键或4个空格来实现缩进。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# if，else可以和elif（else if）组合，形成连续的判断。\n",
    "if current_hour <= 9:\n",
    "    print('讲课进度偏快了')\n",
    "elif current_hour > 10:\n",
    "    print('进度偏慢，后面要快点了')\n",
    "else:\n",
    "    print('讲课进度还可以')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`if`也可以单独使用，不加else。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if 2<1:\n",
    "    print(\"True\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.2 for 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "for循环用于遍历任何序列的项目，如一个列表或者一个字符串。\n",
    "<img src=\"https://www.runoob.com/wp-content/uploads/2013/11/A71EC47E-BC53-4923-8F88-B027937EE2FF.jpg\" width=\"500\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "progress = ['1. 简介与工具准备','2. python基础语法','3. python变量类型','4. 控制流','5. 函数','6. 类','7. 模块','8. python+grasshopper']\n",
    "i=0\n",
    "for p in progress:\n",
    "    print(p)\n",
    "    print(\"loop\",i)\n",
    "    i+=1# i = i+1\n",
    "    #time.sleep(1) #暂停1秒"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "除了用于遍历列表以外，`for`循环也常与`range()`一起使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "range(5) #注意是从0开始"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(len(progress)):\n",
    "    print(i)\n",
    "    print(progress[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.3 while 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "while循环用于循环执行某段程序，直到不满足循环条件时终止。\n",
    "<img src=\"https://www.runoob.com/wp-content/uploads/2013/11/886A6E10-58F1-4A9B-8640-02DBEFF0EF9A.jpg\" width=\"500\">"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#使用while循环打印斐波那契数列\n",
    "i = 0\n",
    "j = 1\n",
    "fi = 0\n",
    "while fi < 500:\n",
    "    fi = i+j\n",
    "    i= j\n",
    "    j= fi\n",
    "    print(fi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.4 循环的跳过(continue)与退出(break)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`continue`能**跳过**循环体中剩余的代码，直接进入下一轮循环。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = 0\n",
    "j = 1\n",
    "fi = 0\n",
    "while fi < 500:\n",
    "    fi = i+j\n",
    "    i= j\n",
    "    j= fi\n",
    "    if fi%2 == 0:\n",
    "        continue  #当fi为偶数时，跳过print，进入下一循环\n",
    "    print(fi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`break`能直接**跳出**当前循环体，结束循环。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = 0\n",
    "j = 1\n",
    "fi = 0\n",
    "while fi < 500:\n",
    "    fi = i+j\n",
    "    i= j\n",
    "    j= fi\n",
    "    print(fi)\n",
    "    if fi%11 == 0:\n",
    "        break    #当fi为11的倍数时，结束循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.5 练习题：操作列表、字典<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "本题通过爬虫的方式抓取了[ArchDaily首页](https://www.archdaily.com/)的链接标题，以列表形式存储在变量`titles`中。\n",
    "但我们注意到，`titles`中既有建筑项目，其中包含了 **项目名称** 和 **建筑事务所/建筑师**，二者用` / `分隔开，如 *Huong An Vien Visiting Center / VTN Architects*；同时也有非建筑项目的文章标题，其中通常不含`/`，如*How Do Insulated Panels Work? Technical Diagrams on Sustainable Building Envelopes*。\n",
    "\n",
    "请尝试去除`titles`中非建筑项目的标题，仅保留建筑项目标题。然后将其整理为 **{项目名称：建筑事务所/建筑师}** 的字典形式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import re\n",
    "url='https://www.archdaily.com/'\n",
    "headers={'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36'}\n",
    "text = requests.get(url,headers=headers).text\n",
    "titles=re.findall(\"<span itemprop=\\'name\\'>(.*?)</span>\",text)\n",
    "titles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "########在此行以下输入代码，完成题目要求\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "#######输入代码结束\n",
    "print(dict_program)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出如：  {'Cana Guesthouse ': ' Carl Gerges Architects',\n",
    "        'HOMEmade Family Houses ': ' Studio Anna Heringer',\n",
    "        'CDK GLOBAL Offices ': ' modulus', \n",
    "        'Olival Street House ': ' ARX Portugal', \n",
    "        'House T ': ' LANZA Atelier', \n",
    "        'Apartment for an Engineer ': ' CXE MA', \n",
    "        'Rhapsody in West Residential Development ': ' TANGRAM architecture and urban landscape', \n",
    "        'Monumen(t)huis Office Renovation  ': ' Declerck-Daels, Architecten', \n",
    "        'Helfštýn Castle Palace Reconstruction ': ' Atelier-r', \n",
    "        'Huong An Vien Visiting Center ': ' VTN Architects', \n",
    "        'Henry Koerner Hall Student Residence  ': ' Atelier Kempe Thill', \n",
    "        'Cedar House ': ' arches', \n",
    "        'Freshly Store ': ' CuldeSac', \n",
    "        'Summer Friend House ': ' Phidias Indonesia'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 函数 Function\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "函数在编程中指一段可复用的代码。使用函数有助于简化代码，便于理解和修改。 \n",
    "\n",
    "在python中采用`def`关键字进行函数的定义。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "来看一个简单的数学问题，对于：\n",
    "$$\n",
    "f(n)\n",
    "\\begin{cases}\n",
    "\\cfrac n2, &if\\ n\\ is\\ even\\\\\n",
    "3n + 1, &if\\  n\\ is\\ odd\n",
    "\\end{cases}\n",
    "$$\n",
    "我们现在可以用python代码来表达：\n",
    "```python\n",
    "if n%2 == 0:\n",
    "    f_n = n/2\n",
    "else:\n",
    "    f_n = 3*n+1\n",
    "```\n",
    "如果我们需要计算\n",
    "$$ f(3)+f(4)*f(5)$$\n",
    "不使用函数的话，我们可以这样写："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "a = 3\n",
    "b = 4\n",
    "c = 5\n",
    "\n",
    "##计算f(3)\n",
    "if a%2 == 0:\n",
    "    f_a = a/2\n",
    "else:\n",
    "    f_a = 3*a+1\n",
    "    \n",
    "##计算f(4)\n",
    "if b%2 == 0:\n",
    "    f_b = b/2\n",
    "else:\n",
    "    f_b = 3*b+1\n",
    "    \n",
    "##计算f(5)\n",
    "if c%2 == 0:\n",
    "    f_c = c/2\n",
    "else:\n",
    "    f_c = 3*c+1\n",
    "    \n",
    "print('f(3) + f(4) * f(5) =',f_a+f_b*f_c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以观察到其中大部分代码是**重复**的。对于这类简单的问题，我们尚且可以使用循环来简化。但面对更复杂的问题，函数的重要性就显现出来了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def f(n):            #def关键字，定义函数名称为f，函数的输入为n\n",
    "    \n",
    "    if n%2 == 0:     #函数体，注意缩进\n",
    "        f_n = n/2\n",
    "    else:\n",
    "        f_n = 3*n+1\n",
    "        \n",
    "    return f_n       #return关键字，函数的返回值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f(3) #验证函数正确"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当定义完成函数之后，前述问题可以用一行代码简单实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('f(3) + f(4) * f(5) =',f(3) + f(4) * f(5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，函数中的变量存在**作用域**的问题，函数以外不能调用函数里层的变量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def func(x):\n",
    "    a = 5\n",
    "    return a * x\n",
    "\n",
    "b = 3\n",
    "#a = func(b)\n",
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个例子可以看到，打印的 a 是函数体以外的 a ，而不是函数体内的 a。这是由于作用域的原因，更深入下去还有形式参数与实际参数的区分问题，暂不赘述。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.1 常用的python内置函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`print()`和`input()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = input('input')\n",
    "print('output'a,)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`sum()`数值求和"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "list_n = [1,2,3,4,5]\n",
    "sum(list_n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`max()`数值求最大，`min()`数值求最小"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "list_n = [1,2,3,4,5]\n",
    "max(list_n), min(list_n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`abs()`绝对值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "abs(-5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`bin()`转化为二进制字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bin(20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`zip()`打包配对"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "name = ['a','b','c']\n",
    "num = [1,2,3]\n",
    "z = zip(name,num)\n",
    "list(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5.2 练习题：斐波那契函数封装<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "试将斐波那契数列封装为函数形式。使得：\n",
    "- Fibonacci(0) = 1\n",
    "- Fibonacci(1) = 1\n",
    "- Fibonacci(2) = 2\n",
    "- Fibonacci(3) = 3\n",
    "- Fibonacci(4) = 5\n",
    "- ...\n",
    "\n",
    "注：循环 v.s.递归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Fibonacci(idx):\n",
    "    \n",
    "    ########在此行以下输入代码，完成题目要求\n",
    "    i=0\n",
    "    j=1\n",
    "    if idx == 0:\n",
    "        fi=1\n",
    "        \n",
    "    for n in range(idx):\n",
    "        fi = i+j\n",
    "        i= j\n",
    "        j= fi\n",
    "    #######输入代码结束\n",
    "    \n",
    "    return fi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(20):\n",
    "    print(Fibonacci(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Fibonacci_iter(idx):\n",
    "    if idx <=1:\n",
    "        return 1\n",
    "    fi = Fibonacci_iter(idx-1)+Fibonacci_iter(idx-2)\n",
    "    return fi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "for i in range(20):\n",
    "    print(Fibonacci_iter(i),end=' ')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输出如：1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 6. 类 Class\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由以上的知识，我们已经可以实现大部分的**面向过程**编程了。所谓面向过程是一种以过程为中心的编程思想。这些都是以什么正在发生为主要目标进行编程，不同于面向对象的是谁在受影响。许多时候面向过程的思考方式是不直观的、不自然的，与之对应的是**面向对象**的编程方式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python从设计之初就已经是一门面向对象的语言，正因为如此，在Python中创建一个类和对象是很容易的。\n",
    "如果以前没有接触过面向对象的编程语言，那我们可能需要先了解一些面向对象思想的一些基本知识。\n",
    "\n",
    "* **类(Class)：** 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 \n",
    " \n",
    " \n",
    "* **类变量：**类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 \n",
    "\n",
    "\n",
    "* **类方法：**类中定义的函数。\n",
    "\n",
    "\n",
    "* **实例化：**创建一个类的实例，类的具体对象。 \n",
    " \n",
    " \n",
    "* **对象：**通过类定义的数据结构实例。对象包括两个数据成员（类变量和实例变量）和方法。 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们通过以下一个银行账户转账的简单例子大致感受一下面向对象的编程方式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Account:                               #定义一个名叫Account的类\n",
    "    \n",
    "    def __init__(self, name, balance):       #__init__()方法是类的初始化函数，是必须的，self关键字表示是类的成员\n",
    "        self.name = name                     #定义了类成员变量name\n",
    "        self.balance = balance               #定义了类成员变量balance\n",
    "        \n",
    "    def transfer(self, receiver, amount):    #定义类的成员函数transfer，实现转账功能。所有类成员函数必须包含参数self。\n",
    "        if self.balance < amount:\n",
    "            print('账户:',self.name,'余额不足')\n",
    "        else:\n",
    "            self.balance = self.balance - amount\n",
    "            receiver.balance = receiver.balance + amount\n",
    "            print('已转账',amount)\n",
    "            \n",
    "    def check_balance(self):                 #定义类的成员函数check_balance，实现余额查询功能。\n",
    "        print('账户:',self.name,'余额:',self.balance)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "至此，我们定义的Account类中包含以下成员：\n",
    "* 类变量\n",
    " * name \n",
    " * balance \n",
    "\n",
    "* 类方法\n",
    " * transfer() \n",
    " * check_balance() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account_a = Account(name='A',balance=50)  #类的实例化，传入的参数即__init__()要求传入的变量，除去self\n",
    "account_b = Account(name='B',balance=100) #这里的account_a, account_b就称为对象(Object)\n",
    "\n",
    "account_a.check_balance()  #对象可以用 object.method()的方法调用自身的成员方法\n",
    "account_b.check_balance()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account_a.transfer(receiver=account_b,amount=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account_a.transfer(receiver=account_b,amount=50)\n",
    "\n",
    "account_a.check_balance()\n",
    "account_b.check_balance()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "对**面向对象**的编程方式有了一个大概的了解之后，我们在回过头想：同样的账户与转账的操作，用**面向过程**的方式会怎么写？\n",
    "\n",
    "我们可能会需要一个**字典**储存账户名和余额，另外创建一个**函数**来实现字典的修改，即转账功能。\n",
    "\n",
    "不难感受到，面向对象的思考方式是**更自然的，更接近现实的**。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.1 类的继承"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "面向对象编程 (OOP) 语言的一个主要功能就是**“继承”**。继承是指这样一种能力：它可以使用现有类的所有功能，并在无需重新编写原来的类的情况下对这些功能进行扩展。\n",
    "通过继承创建的新类称为**“子类”**或“派生类”，被继承的类称为“基类”、**“父类”**或“超类”。\n",
    "\n",
    "接下来我们通过继承上述的Account类，创建拥有密码属性的子类EncryptAccount："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class EncryptAccount(Account):  #定义一个名叫EncryptAccount的类，继承自Account类\n",
    "    \n",
    "    def __init__(self, name, balance, passwd):       \n",
    "        Account.__init__(self, name, balance) # 调用父类的初始化\n",
    "        self.passwd = passwd\n",
    "        \n",
    "    def transfer(self, receiver, amount, passwd): # 重写父类的transfer方法，加入密码验证\n",
    "        if passwd != self.passwd:\n",
    "            print('密码错误')\n",
    "            return    \n",
    "        if self.balance < amount:\n",
    "            print('账户:',self.name,'余额不足')\n",
    "            return\n",
    "        self.balance = self.balance - amount\n",
    "        receiver.balance = receiver.balance + amount\n",
    "        print('已转账',amount)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encrypt_account_a = EncryptAccount(name='A',balance=50,passwd='ac_a')  \n",
    "encrypt_account_b = EncryptAccount(name='B',balance=100,passwd='ac_b') \n",
    "\n",
    "encrypt_account_a.check_balance() \n",
    "encrypt_account_b.check_balance() # 子类EncryptAccount直接继承了父类Account的`check_balance() `方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encrypt_account_a.transfer(receiver=encrypt_account_b,amount=30,passwd='ac') # 重写的transfer方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "encrypt_account_a.transfer(receiver=encrypt_account_b,amount=30,passwd='ac_a')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "encrypt_account_a.check_balance()  \n",
    "encrypt_account_b.check_balance()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6.2 练习题：类的继承<img src=\"https://cdn.iconscout.com/icon/premium/png-512-thumb/homework-1499640-1269824.png\" width=\"30\" div align=\"right\"/>\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "试实现子类CreditAccount（继承自Account父类），使账户拥有各自的信用额度属性credit，并重写父类的transfer方法，转账时允许账户透支相应的信用额度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class CreditAccount(Account):  #定义一个名叫CreditAccount的类，继承自Account类\n",
    "    \n",
    "    def __init__(self, name, balance, credit):       \n",
    "        ########在此行以下输入代码，完成题目要求\n",
    "\n",
    "\n",
    "\n",
    "        #######输入代码结束\n",
    "        \n",
    "    def transfer(self, receiver, amount): # 重写父类的transfer方法，允许账户透支相应的信用额度\n",
    "        ########在此行以下输入代码，完成题目要求\n",
    "\n",
    "\n",
    "\n",
    "        #######输入代码结束"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "credit_account_a = CreditAccount(name='A',balance=50, credit=100)  \n",
    "credit_account_b = CreditAccount(name='B',balance=100, credit= 0) \n",
    "\n",
    "credit_account_a.check_balance()\n",
    "credit_account_b.check_balance() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "credit_account_a.transfer(receiver=credit_account_b,amount=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "credit_account_a.transfer(receiver=credit_account_b,amount=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "credit_account_a.check_balance()\n",
    "credit_account_b.check_balance() "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 7. 模块\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "又称**库**，其中包含了**子模块**、**类**和**方法**。比如用于数学运算的math、numpy，用于数据分析的pandas，用于数据可视化的matplotlib，用于机器学习的pytorch、tensorflow。正是这些丰富而强大的模块，使得python在数据科学领域如此流行。\n",
    "\n",
    "这些库有些是python内置的，称为**标准模块**；另外一些是需要我们自行安装的，称为**第三方模块**。当我们通过安装Anaconda来安装python的时候，Anaconda已经帮我们把许多常用的数据科学相关的第三方模块安装好了，这也是为什么我们开头推荐大家使用Anaconda。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可能注意到了，我们在 ***2.2 节*** 使用了语句`import time`，其中`time`就是python内置的一个标准模块，`import`是引入模块的关键字。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import time\n",
    "print('Hello World!')\n",
    "print('现在是 '+time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "引入time模块之后，我们通过`time.localtime()`调用time模块的localtime()方法，获得了当前的时间。再通过time模块的strftime()方法，将当前时间格式化为\n",
    "\n",
    "\"%Y-%m-%d %H:%M:%S\"\n",
    "\n",
    "的格式，然后打印输出。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "模块引用语法即\n",
    "```python\n",
    "import library\n",
    "```\n",
    "同时也有 \n",
    "```python\n",
    "from library import name\n",
    "```\n",
    "和\n",
    "```python\n",
    "from library import name as nm\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`from…import…` 语句不引入整个模块，而是只引入其中一部分。`as`可以用简写进行重命名，以方便后续编程。如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy \n",
    "numpy.random.randint(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "np.random.randint(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy import random\n",
    "random.randint(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from numpy import random as rand\n",
    "rand.randint(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这是通过引入numpy的随机数子模块来产生0~10随机整数的一个例子。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.1 标准模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* datetime 日期时间\n",
    "* math 数学计算\n",
    "* os 操作系统、文件操作\n",
    "* sys 操作系统、文件操作\n",
    "* urllib 网页、爬虫\n",
    "* re 正则表达式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.2 第三方模块"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* numpy 加速的数学计算\n",
    "* scipy 科学计算\n",
    "* pandas 统计\n",
    "* matplotlib 数据可视化\n",
    "* seaborn 数据可视化\n",
    "* sci-learn 机器学习\n",
    "* pytorch 神经网络\n",
    "* tensorflow 神经网络"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 8. python+grasshopper\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python被称为**胶水语言**，常被用来连接软件组件，适合与其它语言、工具协同工作。\n",
    "\n",
    "而我们常用的python/grasshopper，就比较好地设计了python的接口。这使得我们可以方便地使用python来处理grasshopper原生难以解决的问题，如while循环等。\n",
    "\n",
    "<img src=\"https://developer.rhino3d.com/images/ghpython-component-detail.png\" width=\"500\">\n",
    "\n",
    "Rhinoceros官方也提供了详细的文档：[python for rhino/grasshopper 文档](https://developer.rhino3d.com/api/RhinoScriptSyntax/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来我们以地块退红线问题为例，展示python在grasshopper程序中可以发挥的简化作用。\n",
    "```python\n",
    "import rhinoscriptsyntax as rs\n",
    "#import Rhino.Geometry as rg\n",
    "#import ghpythonlib.components as ghcomp\n",
    "\n",
    "center = rs.CurveAreaCentroid(curve)[0]\n",
    "points = rs.CurvePoints(curve)\n",
    "S = 0\n",
    "for i in range(len(points)-1):\n",
    "    S += points[i][0]*points[i+1][1]-points[i][1]*points[i+1][0]\n",
    "S /=2\n",
    "\n",
    "curve_unified = curve\n",
    "\n",
    "if S >= 0:\n",
    "    rs.ReverseCurve(curve_unified)\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 9. 总结\n",
    "***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 1. 简介与工具准备\n",
    "    - 1.1 Python历史\n",
    "    - 1.2 Anaconda安装\n",
    "    - 1.3 jupyter notebook使用\n",
    "        - 1.3.1 jupyter notebook 在线试用\n",
    "        - 1.3.2 本地使用jupyter notebook\n",
    "        - 1.3.3 新建个人目录/程序/终端环境\n",
    "        - 1.3.4 熟悉工具栏操作\n",
    "        - 1.3.5 熟悉快捷键操作\n",
    "    - 1.4 练习题：熟悉jupyter notebook操作\n",
    "- 2. python基础语法\n",
    "    - 2.1 = 赋值\n",
    "    - 2.2 print()与input()\n",
    "    - 2.3 注释\n",
    "    - 2.4 练习题：多边形面积\n",
    "- 3. python变量类型\n",
    "    - 3.1 数值类型 Number\n",
    "        - 3.1.1 算数运算符\n",
    "        - 3.1.2 比较运算符\n",
    "        - 3.1.3 逻辑运算符\n",
    "    - 3.2 字符串类型 String\n",
    "        - 3.2.1 字符串索引与切片\n",
    "        - 3.2.2 字符串split，join\n",
    "    - 3.3 元组 Tuple，列表 List，字典 Dictionary，集合Set\n",
    "        - 3.3.1 元组 Tuple\n",
    "        - 3.3.2 列表 List\n",
    "        - 3.3.3 字典 Dictionary\n",
    "        - 3.3.4 集合 Set\n",
    "    - 3.4 类型转换\n",
    "    - 3.5 练习题：字符串拼接整理\n",
    "- 4. 控制流\n",
    "    - 4.1 if-else\n",
    "    - 4.2 for 循环\n",
    "    - 4.3 while 循环\n",
    "    - 4.4 循环的跳过(continue)与退出(break)\n",
    "    - 4.5 练习题：操作列表、字典\n",
    "- 5. 函数 Function\n",
    "    - 5.1 常用的python内置函数\n",
    "    - 5.2 练习题：斐波那契函数封装\n",
    "- 6. 类 Class\n",
    "    - 6.1 类的继承\n",
    "    - 6.2 练习题：类的继承\n",
    "- 7. 模块\n",
    "    - 7.1 标准模块\n",
    "    - 7.2 第三方模块\n",
    "- 8. python+grasshopper"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "09c9bc422b3f9e191669d3966229799ceb69c5def4bfec52b5a05cff94511f9c"
  },
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
